import json
import random

from django.http import HttpResponseBadRequest
from django.http import HttpResponseForbidden
from django.http import HttpResponseNotFound

from users.models import User
from utils.access_token import *
from verifications.constants import *
from django.http import HttpResponse
from django.http import JsonResponse
from django.shortcuts import render
from utils.response_code import RETCODE, err_msg

from django.views import View
from django_redis import get_redis_connection

from libs.captcha.captcha import captcha


class ImageCodeView(View):
    def get(self, request, image_code_id):
        text, image_data = captcha.generate_captcha()

        redis_conn = get_redis_connection('verify_code')
        redis_conn.setex('image_code_%s' % image_code_id, REDIS_IMAGE_CODE_EXPIRES, text)

        return HttpResponse(image_data, content_type='image/jpeg')


class SmsCodeView(View):
    def get(self, request, mobile):
        data = request.GET
        image_code = data.get('image_code')
        image_code_id = data.get('image_code_id')

        if not all([mobile, image_code, image_code_id]):
            return JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': err_msg[RETCODE.NECESSARYPARAMERR]})

        redis_cli = get_redis_connection('verify_code')
        redis_code = redis_cli.get('image_code_' + image_code_id)

        if redis_code:
            redis_code = redis_code.decode()

        if image_code.upper() != redis_code:
            return JsonResponse({'code': 9999, 'errmsg': '图片验证码错误'})

        flag = redis_cli.get('flag_' + mobile)
        if flag:
            return JsonResponse({'code': 9999, 'errmsg': '验证码频繁发送'})

        sms_code = '%06d' % random.randint(0, 999999)
        print(sms_code)

        redis_cli.setex(mobile, 300, sms_code)
        redis_cli.delete('image_code_' + image_code_id)

        # from celery_task.main import send_sms_code
        # send_sms_code.delay(mobile, sms_code)


        redis_cli.setex('flag_' + mobile, 60, 1)

        return JsonResponse({'code': 0, 'errmsg': 'OK'})


class FindPasswordImageCodeView(View):
    def get(self, request, username):
        text = request.GET.get('text')
        image_code_id = request.GET.get('image_code_id')
        if not all([username, text, image_code_id]):
            return HttpResponseNotFound()

        try:
            user = User.objects.get(username=username)
        except:
            return HttpResponseNotFound()

        redis_client = get_redis_connection('verify_code')
        image_code = redis_client.get('image_code_%s' % image_code_id)
        if not image_code:
            return HttpResponseNotFound()
        else:
            image_code = image_code.decode()

        if text.lower() == image_code.lower():
            res = {
                'code': 0,
                'errmsg': 'OK',
                'mobile': user.mobile,
                'access_token': str(generate_access_token(username))
            }
            return JsonResponse(res)

        else:
            return HttpResponseBadRequest('wrong image code')


class FindPasswordSmsCodeView(View):
    def get(self, request):
        token = request.GET.get('access_token')

        username = decode_access_token(token)
        if not username:
            return HttpResponseNotFound('error token')

        try:
            user = User.objects.get(username=username)
        except:
            return HttpResponseNotFound('error token')

        from random import randint
        sms_code = '%06d' % randint(0, 999999)
        print(sms_code)

        from main import send_sms_code
        send_sms_code.delay(user.mobile, sms_code)

        redis_cli = get_redis_connection('verify_code')
        redis_cli.setex('sms_code_%s' % user.mobile, 300, sms_code)

        return JsonResponse({'code': 0, 'errmsg': 'OK'})


class CheckSmsCodeView(View):
    def get(self, request, username):

        sms_code = request.GET.get('sms_code')

        if not sms_code:
            return HttpResponseBadRequest()

        try:
            user = User.objects.get(username=username)
        except:
            return HttpResponseNotFound()

        redis_client = get_redis_connection('verify_code')
        mobile_code = redis_client.get('sms_code_%s' % user.mobile).decode()

        if mobile_code != sms_code:
            return HttpResponseBadRequest()

        res = {
            'code': 0,
            'errmsg': 'OK',
            'user_id': user.id,
            'access_token': generate_access_token(username)
        }
        return JsonResponse(res)
